using Nop.Core.Domain.Messages;
using Nop.Plugin.ActiveForever.ActiveChat.Data;
using Nop.Plugin.ActiveForever.ActiveChat.Models;
using Nop.Plugin.ActiveForever.ActiveChat.Services;
using Nop.Services.Configuration;
using Nop.Services.Messages;
using Nop.Web.Framework.Controllers;
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Web;
using System.Web.Mvc;
using System.Xml;

namespace Nop.Plugin.ActiveForever.ActiveChat.Controllers
{
	public class ActiveChatController : Controller
	{
		private readonly ActiveChatSettings _activeChatSettings;

		private readonly ISettingService _settingService;

		private readonly IEmailAccountService _emailAccountService;

		private readonly IQueuedEmailService _queuedEmailService;

		private readonly IActiveChatService _activeChatService;

		public ActiveChatController(ActiveChatSettings activeChatSettings, ISettingService settingsService, IEmailAccountService emailAccountService, IQueuedEmailService queuedEmailService, IActiveChatService activeChatService)
		{
			_activeChatSettings = activeChatSettings;
			_settingService = settingsService;
			_emailAccountService = emailAccountService;
			_queuedEmailService = queuedEmailService;
			_activeChatService = activeChatService;
		}

		[AdminAuthorize]
		public ActionResult ActivateAccount(string chargeId)
		{
			return new RedirectResult("/Admin/Widget/ConfigureWidget?systemName=ActiveForever.ActiveChat");
		}

		[AdminAuthorize]
		public ActionResult ActiveChat()
		{
			ActiveChatModel activeChatModel = new ActiveChatModel
			{
				OperatorWelcomeMessage = _activeChatSettings.OperatorWelcomeMessage,
			};

            List<ClientChatLog> list = _activeChatService.GetAllClientChatLogs().ToList();
			List<string> strs = new List<string>();
			int minutes = 0;
			int count = 0;
			foreach (ClientChatLog clientChatLog in list)
			{
				XmlDocument xmlDocument = new XmlDocument();
				xmlDocument.LoadXml(clientChatLog.Transcript);
				XmlNodeList elementsByTagName = xmlDocument.GetElementsByTagName("Message");
				string empty = string.Empty;
			    DateTime dateTime = Convert.ToDateTime(elementsByTagName[0].Attributes["TimeStamp"].InnerText);
				DateTime dateTime1 = Convert.ToDateTime(elementsByTagName[elementsByTagName.Count - 1].Attributes["TimeStamp"].InnerText);
				minutes = minutes + (dateTime1 - dateTime).Minutes;
				count = count + elementsByTagName.Count;
				foreach (XmlNode xmlNodes in elementsByTagName)
				{
					if (xmlNodes.Attributes["Sender"].InnerText.ToLower().Contains("system"))
					{
						empty = xmlNodes.Attributes["Recipient"].InnerText;
					}
					if (string.IsNullOrEmpty(empty) || xmlNodes.Attributes["Sender"].InnerText != empty || xmlNodes.Attributes["Recipient"].InnerText.ToLower().Contains("system"))
					{
						continue;
					}
					string innerText = xmlNodes.Attributes["Recipient"].InnerText;
					strs.Add(innerText);
					break;
				}
			}
			Dictionary<string, int> strs1 = (from o in strs group o by o).ToDictionary(strs2 => strs2.Key, strs2 => (from o in strs where o == strs2.Key select o).Count<string>());
		    activeChatModel.TotalChatCount = list.Count();
			activeChatModel.TotalBannedClients = _activeChatService.GetAllBannedClients().Count();
			if (strs.Count <= 0)
			{
				activeChatModel.MostActiveOperator = "n/a";
			}
			else
			{
				ActiveChatModel activeChatModel1 = activeChatModel;
				KeyValuePair<string, int> keyValuePair = (
					from o in strs1
					orderby o.Key
					select o).FirstOrDefault<KeyValuePair<string, int>>();
				string key = keyValuePair.Key;
				KeyValuePair<string, int> keyValuePair1 = (
					from o in strs1
					orderby o.Key
					select o).FirstOrDefault<KeyValuePair<string, int>>();
				activeChatModel1.MostActiveOperator = string.Concat(key, " - ", keyValuePair1.Value);
			}
			if (list.Count <= 0)
			{
				activeChatModel.AverageChatTime = new decimal(0);
				activeChatModel.AverageMessagesPerChat = new decimal(0);
			}
			else
			{
				activeChatModel.AverageChatTime = minutes / list.Count<ClientChatLog>();
				activeChatModel.AverageMessagesPerChat = count / list.Count<ClientChatLog>();
			}
            return View("~/Plugins/ActiveForever.ActiveChat/Views/ActiveChat/ActiveChat.cshtml", activeChatModel);
		}

		public ActionResult ActiveChatClient()
		{
			ActiveChatModel activeChatModel = new ActiveChatModel()
			{
				ClientWelcomeMessageOnline = _activeChatSettings.ClientWelcomeMessageOnline,
				ClientWelcomeMessageOffline = _activeChatSettings.ClientWelcomeMessageOffline,
				ChatWindowHeight = _activeChatSettings.ChatWindowHeight,
				ChatWindowWidth = _activeChatSettings.ChatWindowWidth
			};
            return View("~/Plugins/ActiveForever.ActiveChat/Views/ActiveChat/ActiveChatClient.cshtml", activeChatModel);
		}

		[AdminAuthorize]
		public ActionResult ActiveChatHelp()
		{
            return View("~/Plugins/ActiveForever.ActiveChat/Views/ActiveChat/ActiveChatHelp.cshtml");
		}

		[AdminAuthorize]
		public ActionResult ChargeCard(string stripeToken)
		{
            return RedirectToRoute("~/Plugins/ActiveForever.ActiveChat/Views/ActiveChat/ActiveChat.cshtml");
		}

		public ActionResult Configure()
		{
			ActiveChatModel activeChatModel = new ActiveChatModel
			{
				OperatorWelcomeMessage = _activeChatSettings.OperatorWelcomeMessage,
				ChatWindowHeight = _activeChatSettings.ChatWindowHeight,
				ChatWindowWidth = _activeChatSettings.ChatWindowWidth,
				ClientWelcomeMessageOnline = _activeChatSettings.ClientWelcomeMessageOnline,
				ClientWelcomeMessageOffline = _activeChatSettings.ClientWelcomeMessageOffline,
				PostChatEmail = _activeChatSettings.PostChatEmail,
				PostChatEmailSubject = _activeChatSettings.PostChatEmailSubject,
				ConfiguredEmailAccounts = new List<ConfiguredEmailAccount>(),
				ActiveChatDataExports = new List<string>(),
				EnablePostChatEmail = _activeChatSettings.EnablePostChatEmail,
				StaticFileName = _activeChatSettings.StaticFileName,
				WidgetImage = _activeChatSettings.WidgetImage
			};
			foreach (EmailAccount allEmailAccount in _emailAccountService.GetAllEmailAccounts())
			{
				List<ConfiguredEmailAccount> configuredEmailAccounts = activeChatModel.ConfiguredEmailAccounts;
				ConfiguredEmailAccount configuredEmailAccount = new ConfiguredEmailAccount
				{
					AccountName = allEmailAccount.DisplayName,
					AccountId = allEmailAccount.Id
				};
				configuredEmailAccounts.Add(configuredEmailAccount);
			}
			string str = Path.Combine(HttpRuntime.AppDomainAppPath, "content\\files\\exportimport");
			string[] files = Directory.GetFiles(str, "*.xml", SearchOption.TopDirectoryOnly);
			foreach (string str1 in files.Where(str1 => str1.Contains("ActiveChatDataExport-")))
			{
			    activeChatModel.ActiveChatDataExports.Add(Path.GetFileName(str1));
			}
            return View("~/Plugins/ActiveForever.ActiveChat/Views/ActiveChat/Configure.cshtml", activeChatModel);
		}

		[FormValueRequired(new[] { "save" })]
		[HttpPost]
		[ValidateInput(false)]
		public ActionResult Configure(ActiveChatModel model)
		{
			_activeChatSettings.ChatWindowWidth = model.ChatWindowWidth;
			_activeChatSettings.ChatWindowHeight = model.ChatWindowHeight;
			_activeChatSettings.OperatorWelcomeMessage = model.OperatorWelcomeMessage;
			_activeChatSettings.ClientWelcomeMessageOnline = model.ClientWelcomeMessageOnline;
			_activeChatSettings.ClientWelcomeMessageOffline = model.ClientWelcomeMessageOffline;
			_activeChatSettings.OfflineEmailAccountId = model.OfflineEmailAccountId;
			_activeChatSettings.PostChatEmail = model.PostChatEmail;
			_activeChatSettings.PostChatEmailSubject = model.PostChatEmailSubject;
			_activeChatSettings.EnablePostChatEmail = model.EnablePostChatEmail;
			_activeChatSettings.WidgetImage = model.WidgetImage;
			try
			{
				_settingService.SaveSetting(_activeChatSettings);
				ViewData["Status"] = "Settings saved.";
			}
			catch
			{
				ViewData["Status"] = "Error saving settings. Please try again.";
			}
			return Configure();
		}

		[ActionName("Configure")]
		[FormValueRequired(new[] { "export" })]
		[HttpPost]
		[ValidateInput(false)]
		public ActionResult ExportData(ActiveChatModel model)
		{
			try
			{
				_activeChatService.GenerateExportFile();
				ViewData["Status"] = "Export completed.";
			}
			catch (Exception exception1)
			{
				Exception exception = exception1;
				ViewData["Status"] = string.Concat("Export failed: ", exception.Message);
			}
			return Configure();
		}

		[ActionName("Configure")]
		[FormValueRequired(new[] { "import" })]
		[HttpPost]
		[ValidateInput(false)]
		public ActionResult ImportData(ActiveChatModel model)
		{
			if (!string.IsNullOrEmpty(model.SelectedImportFile))
			{
				ViewData["Status"] = _activeChatService.Import(model.SelectedImportFile);
			}
			return Configure();
		}

		[AdminAuthorize]
		public JsonResult InsertBannedClient(string name, string clientIp)
		{
		    if ((
		        from c in _activeChatService.GetAllBannedClients()
		        where c.ClientIp == clientIp
		        select c).Any()) return Json(new {result = "ok"}, JsonRequestBehavior.AllowGet);
		    BannedClient bannedClient = new BannedClient
		    {
		        Name = name,
		        ClientIp = clientIp,
		        BannedOn = DateTime.Now.ToShortDateString()
		    };
		    _activeChatService.InsertBannedClient(bannedClient);
		    return Json(new { result = "ok" }, JsonRequestBehavior.AllowGet);
		}

		[AdminAuthorize]
		public JsonResult InsertCannedResponse(string message)
		{
			CannedResponse cannedResponse = new CannedResponse
			{
				Message = message
			};
			_activeChatService.InsertCannedResponse(cannedResponse);
			return Json(new { result = "ok" }, JsonRequestBehavior.AllowGet);
		}

		[AdminAuthorize]
		public JsonResult LoadBannedClients()
		{
			IList<BannedClient> allBannedClients = _activeChatService.GetAllBannedClients();
			return Json(new { bannedClients = allBannedClients.ToList() }, JsonRequestBehavior.AllowGet);
		}

		[AdminAuthorize]
		public JsonResult LoadCannedResponses()
		{
			IList<CannedResponse> allCannedReponses = _activeChatService.GetAllCannedReponses();
			return Json(new { cannedResponses = allCannedReponses.ToList() }, JsonRequestBehavior.AllowGet);
		}

		[AdminAuthorize]
		public JsonResult LoadTranscript(int clientChatLogId)
		{
			ClientChatLog clientChatLog = _activeChatService.GetClientChatLog(clientChatLogId);
			List<TranscriptMessage> transcriptMessages = new List<TranscriptMessage>();
			if (clientChatLog != null)
			{
				XmlDocument xmlDocument = new XmlDocument();
				xmlDocument.LoadXml(clientChatLog.Transcript);
				foreach (XmlNode elementsByTagName in xmlDocument.GetElementsByTagName("Message"))
				{
					TranscriptMessage transcriptMessage = new TranscriptMessage
					{
						Message = elementsByTagName.Attributes["Message"].InnerText,
						Recipient = elementsByTagName.Attributes["Recipient"].InnerText,
						Sender = elementsByTagName.Attributes["Sender"].InnerText
					};
					DateTime dateTime = Convert.ToDateTime(elementsByTagName.Attributes["TimeStamp"].InnerText);
					transcriptMessage.TimeStampJS = dateTime.ToString("MMM dd, HH:mm:ss");
					transcriptMessages.Add(transcriptMessage);
				}
			}
			return Json(new { messages = transcriptMessages }, JsonRequestBehavior.AllowGet);
		}

		[AdminAuthorize]
		public JsonResult LoadTranscripts(bool getRecent)
		{
		    IList<ClientChatLog> clientChatLogs = (!getRecent ? _activeChatService.GetAllClientChatLogs() : _activeChatService.GetRecentClientChatLogs());
		    return Json(new { transcripts = clientChatLogs.ToList() }, JsonRequestBehavior.AllowGet);
		}

	    [ChildActionOnly]
		public ActionResult PublicInfo(string widgetZone)
		{
			ActiveChatModel activeChatModel = new ActiveChatModel
			{
				ChatWindowHeight = _activeChatSettings.ChatWindowHeight,
				ChatWindowWidth = _activeChatSettings.ChatWindowWidth,
				WidgetImage = _activeChatSettings.WidgetImage
			};
            return View("~/Plugins/ActiveForever.ActiveChat/Views/ActiveChat/PublicInfo.cshtml", activeChatModel);
		}

		[AdminAuthorize]
		public JsonResult RemoveBannedClient(int Id)
		{
			_activeChatService.RemoveBannedClient(Id);
			return Json(new { result = "ok" }, JsonRequestBehavior.AllowGet);
		}

		public JsonResult SendOfflineMessage(string name, string email, string message)
		{
			try
			{
				EmailAccount emailAccountById = _emailAccountService.GetEmailAccountById(_activeChatSettings.OfflineEmailAccountId);
				QueuedEmail queuedEmail = new QueuedEmail
				{
				    Priority = 5,
				    From = emailAccountById.Email,
				    FromName = emailAccountById.DisplayName,
				    To = emailAccountById.Email,
				    ToName = emailAccountById.DisplayName,
				    Bcc = string.Empty,
				    CC = string.Empty,
				    Subject = "Live chat offline message"
				};
			    string[] strArrays = { "Name: ", name, "<br />Email: ", email, "<br />Message: ", message };
				queuedEmail.Body = string.Concat(strArrays);
				queuedEmail.CreatedOnUtc = DateTime.UtcNow;
				queuedEmail.EmailAccountId = emailAccountById.Id;
				_queuedEmailService.InsertQueuedEmail(queuedEmail);
			}
			catch
			{
			}
			return Json(new { result = "sent" }, JsonRequestBehavior.AllowGet);
		}
	}
}